package String中的流式编程;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StringStreamExamples {

    public static void main(String[] args) {
        // 模拟生产环境数据
        List<String> logs = Arrays.asList(
            "ERROR: 2023-05-20 10:23:45 Database connection failed",
            "INFO: 2023-05-20 10:24:10 User 12345 logged in",
            "WARN: 2023-05-20 10:25:30 High memory usage detected (85%)",
            "ERROR: 2023-05-20 10:26:15 Payment processing timeout",
            "INFO: 2023-05-20 10:30:00 New user registered: user@example.com"
        );
        
        List<String> emails = Arrays.asList(
            "john.doe@example.com",
            "invalid-email",
            "sarah.connor@company.org",
            "contact@business.com",
            "bad_format@.com"
        );
        
        String text = "Java Stream API provides an efficient way to process collections of objects";

        // ===================================================================
        // 1. 日志分析：提取所有ERROR级别的日志 (Filter + Collect)
        // 场景：生产环境日志监控系统
        // ===================================================================
        List<String> errorLogs = logs.stream()
            .filter(log -> log.startsWith("ERROR:"))
            .collect(Collectors.toList());
        System.out.println("==== 错误日志 ====\n" + errorLogs);

        // ===================================================================
        // 2. 数据清洗：验证并提取有效邮箱 (Filter + Pattern)
        // 场景：用户注册系统数据清洗
        // ===================================================================
        List<String> validEmails = emails.stream()
            .filter(email -> email.matches("^[\\w.-]+@[\\w.-]+\\.[a-z]{2,6}$"))
            .collect(Collectors.toList());
        System.out.println("\n==== 有效邮箱 ====\n" + validEmails);

        // ===================================================================
        // 3. 数据转换：提取日志中的时间戳 (Map)
        // 场景：日志时间序列分析
        // ===================================================================
        List<String> timestamps = logs.stream()
            .map(log -> log.substring(6, 25))  // 提取时间部分
            .collect(Collectors.toList());
        System.out.println("\n==== 日志时间戳 ====\n" + timestamps);

        // ===================================================================
        // 4. 关键词统计：计算文本中单词出现频率 (FlatMap + GroupingBy)
        // 场景：文本分析/SEO优化
        // ===================================================================
        Map<String, Long> wordFrequency = Arrays.stream(text.split("\\s+"))
            .map(String::toLowerCase)
            .map(word -> word.replaceAll("[^a-z]", ""))  // 移除非字母字符
            .filter(word -> !word.isEmpty())
            .collect(Collectors.groupingBy(
                word -> word, 
                Collectors.counting()
            ));
        System.out.println("\n==== 词频统计 ====\n" + wordFrequency);

        // ===================================================================
        // 5. 数据聚合：拼接所有日志内容 (Reduce)
        // 场景：生成日志摘要报告
        // ===================================================================
        String fullReport = logs.stream()
            .map(log -> log + "\n")  // 每行添加换行符
            .reduce("", String::concat);
        System.out.println("\n==== 完整日志报告 ====\n" + fullReport);

        // ===================================================================
        // 6. 数据验证：检查是否有内存警告 (AnyMatch)
        // 场景：系统健康监控
        // ===================================================================
        boolean memoryWarning = logs.stream()
            .anyMatch(log -> log.contains("memory usage") && log.startsWith("WARN:"));
        System.out.println("\n==== 内存警告存在: " + memoryWarning + " ====");

        // ===================================================================
        // 7. 数据提取：从日志中提取所有用户ID (FlatMap + Pattern)
        // 场景：用户行为分析
        // ===================================================================
        List<Long> userIds = logs.stream()
            .flatMap(log -> Arrays.stream(log.split(" ")))  // 分割单词
            .filter(word -> word.matches("\\d{5,}"))       // 匹配5位以上数字
            .map(Long::valueOf)
            .distinct()  // 去重
            .collect(Collectors.toList());
        System.out.println("\n==== 用户ID列表 ====\n" + userIds);

        // ===================================================================
        // 8. 字符串处理：首字母大写转换 (Map)
        // 场景：用户姓名格式化
        // ===================================================================
        List<String> names = Arrays.asList("john doe", "sarah connor", "alex mason");
        List<String> formattedNames = names.stream()
            .map(name -> Arrays.stream(name.split(" "))
                .map(part -> part.substring(0, 1).toUpperCase() + part.substring(1))
                .collect(Collectors.joining(" ")))
            .collect(Collectors.toList());
        System.out.println("\n==== 格式化姓名 ====\n" + formattedNames);

        // ===================================================================
        // 9. 数据分组：按日志级别分组 (GroupingBy)
        // 场景：日志分类统计
        // ===================================================================
        Map<String, List<String>> logsByLevel = logs.stream()
            .collect(Collectors.groupingBy(
                log -> log.substring(0, log.indexOf(':'))
            ));
        System.out.println("\n==== 按日志级别分组 ====");
        logsByLevel.forEach((level, logList) -> 
            System.out.println(level + " -> " + logList.size() + " 条日志"));

        // ===================================================================
        // 10. 数据统计：最长单词查找 (Reduce)
        // 场景：文本分析
        // ===================================================================
        Optional<String> longestWord = Arrays.stream(text.split("\\s+"))
            .map(word -> word.replaceAll("[^a-zA-Z]", ""))
            .filter(word -> !word.isEmpty())
            .reduce((word1, word2) -> 
                word1.length() > word2.length() ? word1 : word2);
        
        longestWord.ifPresent(word -> 
            System.out.println("\n==== 最长单词: " + word + " ===="));

        // ===================================================================
        // 11. 复杂解析：从日志中提取错误码 (FlatMap + Optional)
        // 场景：错误诊断系统
        // ===================================================================
        List<String> errorCodes = logs.stream()
            .filter(log -> log.startsWith("ERROR:"))
            .flatMap(log -> {
                // 模拟从错误消息中提取错误码的模式
                if (log.contains("timeout"))
                {
                    return Stream.of("ERR_TIMEOUT");
                }
                if (log.contains("connection"))
                {
                    return Stream.of("ERR_DB_CONN");
                }
                return Stream.empty(); // 没有错误码则返回空流
            })
            .collect(Collectors.toList());
        System.out.println("\n==== 错误代码 ====\n" + errorCodes);

        // ===================================================================
        // 12. 数据分页：日志分页查询 (Skip + Limit)
        // 场景：日志查看界面分页
        // ===================================================================
        int pageSize = 2;
        int pageNum = 1;
        List<String> logPage = logs.stream()
            .sorted()  // 按自然顺序排序
            .skip((pageNum - 1) * pageSize)
            .limit(pageSize)
            .collect(Collectors.toList());
        System.out.println("\n==== 日志分页 (第 " + pageNum + " 页) ====\n" + logPage);
    }
}